/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#ifndef MK_SIP_MESSAGE_H
#define MK_SIP_MESSAGE_H
#include "MkSipUtil.h"
#include "MkSipHeader.h"

class MkApi CMkSipMessage
{
public:
public:
    CMkSipMessage();
    virtual ~CMkSipMessage();
    Uint32 ParseContent(const Uint8* pBuf, Uint32 nLen, Uint32& nUsed);
    Uint32 ToString(MkString& Content) const;

    void SetTcpFlag(BOOL bTcp) { m_bTcp = bTcp; }
    void SetRemoteHost(const MkString& RemoteHost) { m_RemoteHost = RemoteHost; }
    void SetRemotePort(Uint16 RemotePort) { m_RemotePort = RemotePort; }
    void SetLocalHost(const MkString& LocalHost) { m_LocalHost = LocalHost; }
    void SetLocalPort(Uint16 LocalPort) { m_LocalPort = LocalPort; }
    void SetContactHost(const MkString& ContactHost) { m_ContactHost = ContactHost; }
    void SetContactPort(Uint16 ContactPort) { m_ContactPort = ContactPort; }
    void SetRequestFlag(BOOL bFlag) { m_bRequest = bFlag; }
    void AddHeader(const MkString& strKey, const MkString& strValue);
    void AddOtherHeaders(const MkMapString& MapHeader);
    void SetStatusCode(const MkSipStatus& StatusCode) { m_StatusCode = StatusCode; }
    void SetCSeq(Uint32 SeqNo);
    void SetCSeq(const std::pair<Uint32, MkString>& CSeq) { m_CSeq = CSeq; }
    void SetMethod(const MkSipMethod& Method) { m_Method = Method; }
    void SetSipUri(const CMkSipUri& Uri) { m_Uri = Uri; }
    void SetFrom(const CMkSipFrom& From) { m_From = From; }
    void SetTo(const CMkSipTo& To) { m_To = To; }
    void AddVia(const CMkSipVia& Via) { m_VecVia.push_front(Via); }
    void SetVecVia(const MkList<CMkSipVia>& VecVia) { m_VecVia = VecVia; }
    void SetCallId(const MkString& CallId, const MkString& Info = "") { m_CallId.first = CallId; m_CallId.second = Info; }
    void AddContact(const CMkSipContact& Contact) { m_VecContact.push_back(Contact); }
    void AddRoute(const CMkSipRoute& Route) { m_VecRoute.push_back(Route); }
    void SetVecRoute(const MkVector<CMkSipRoute>& VecRoute) { m_VecRoute = VecRoute; }
    void AddRecordRoute(const CMkSipRecordRoute& RecordRoute) { m_VecRecordRoute.push_back(RecordRoute); }
    void SetVecRecordRouter(const MkVector<CMkSipRecordRoute>& VecRecordRoute) { m_VecRecordRoute = VecRecordRoute; }
    void SetContentType(const CMkSipContentType& ContentType) { m_ContentType = ContentType; }
    void SetContentType(const MkSipContentType& SipContentType);
    void SetContentBody(const MkString& ContentBody) { m_ContentLenght = ContentBody.size(); m_ContentBody = ContentBody; }
    void SetMaxForwards(Uint32 MaxForwards) { m_MaxForwards = MaxForwards; }

    void ClearVia() { m_VecVia.clear(); }
    void RemoveFirstVia() { m_VecVia.pop_front(); }
    void ClearRoute() { m_VecRoute.clear(); }
    void ClearOtherHeaders() { m_MapOtherHeader.clear(); }
    void ClearContact() { m_VecContact.clear(); }

    const MkString& GetRemoteHost() const { return m_RemoteHost; }
    const Uint16& GetRemotePort() const { return m_RemotePort; }
    const MkString& GetLocalHost() const { return m_LocalHost; }
    const Uint16& GetLocalPort() const { return m_LocalPort; }
    const MkString& GetContactHost() const { return m_ContactHost; }
    const Uint16& GetContactPort() const { return m_ContactPort; }
    const MkString& GetCallId() const { return m_CallId.first; }
    const MkSipMethod& GetMethod() const { return m_Method; }
    const MkString& GetBody() const { return m_ContentBody; }
    Uint32 GetHeaderValue(const MkString& strKey, MkString& strValue) const;
    const MkMapString& GetOtherHeaders() const { return m_MapOtherHeader; }
    BOOL IsRequest() const { return m_bRequest; }
    BOOL IsTcp() const { return m_bTcp; }
    const CMkSipFrom& GetFrom() const { return m_From; }
    const CMkSipTo& GetTo() const { return m_To; }
    const CMkSipUri& GetUri() const { return m_Uri; }
    const MkList<CMkSipVia>& GetVecVia() const { return m_VecVia; }
    const MkVector<CMkSipAuthorization>& GetVecAuthorization() const { return m_VecAuthorization; }
    const MkVector<CMkSipWwwAuthenticate>& GetVecWwwAuthenticate() const { return m_VecWwwAuthenticate; }
    const MkVector<CMkSipContact>& GetVecContact() const { return m_VecContact; }
    const MkVector<CMkSipRecordRoute>& GetVecRecordRoute() const { return m_VecRecordRoute; }
    const MkVector<CMkSipRoute>& GetVecRoute() const { return m_VecRoute; }
    BOOL IsEmpty() const { return MkSipMethodEnd == m_Method && MkSipStatusEnd == m_StatusCode; }
    const MkSipStatus& GetStatusCode() const { return m_StatusCode; }
    const std::pair<Uint32, MkString>& GetCSeq() const { return m_CSeq; }
    MkString GetTransactionId() const;
    const MkString& GetDialogId() const;
protected:
private:
    Uint32 ParseHeaderLine(const MkString& strLine);
    Uint32 ParseHeader(const MkString& strHeader, MkString& Key, MkString& Value);
private:
    BOOL                                    m_bRequest;
    BOOL                                    m_bTcp;
    MkString                                m_RemoteHost;
    Uint16                                  m_RemotePort;
    MkString                                m_LocalHost;
    Uint16                                  m_LocalPort;
    MkString                                m_ContactHost;
    Uint16                                  m_ContactPort;
    //request has
    MkString                                m_Version;
    CMkSipUri                               m_Uri;
    MkSipMethod                             m_Method;

    //response has
    MkSipStatus                             m_StatusCode;

    BOOL                                    m_ParseHeaderEnd;
    MkString                                m_ContentBody;

    CMkSipFrom                              m_From;
    CMkSipTo                                m_To;
    CMkSipCallInfo                          m_Call;
    std::pair<Uint32, MkString>             m_CSeq;    //number string method
    std::pair<MkString, MkString>           m_CallId;  //call-id number, call-id host info
    MkList<CMkSipVia>                       m_VecVia;
    MkVector<CMkSipContact>                 m_VecContact;
    Uint32                                  m_ContentLenght;
    CMkSipContentType                       m_ContentType;
    Uint32                                  m_MaxForwards;
    MkVector<CMkSipAcceptEncoding>          m_VecAcceptEncodings;
    MkVector<CMkSipAcceptLanguage>          m_VecAcceptLanguage;
    MkVector<CMkSipRecordRoute>             m_VecRecordRoute;  //response has
    MkVector<CMkSipRoute>                   m_VecRoute;        //request has

    MkVector<CMkSipAuthorization>           m_VecAuthorization;
    MkVector<CMkSipWwwAuthenticate>         m_VecWwwAuthenticate;

    MkMapString                             m_MapOtherHeader;
};


#endif